package lt.mii.optimum.components;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import lt.mii.optimum.Start;

/**
 * Class Represents a single teacher
 * 
 * @author dstrukov
 * 
 */
public class Teacher extends Person {

	private Set<Integer> $daysOff;

	private Map<Subject, Set<Group>> $groups;

	private List<Subject> $subjects;



	public Teacher() {
		$groups = new Hashtable<Subject, Set<Group>>();
		$subjects = new ArrayList<Subject>();
		$daysOff = new HashSet<Integer>();

	}



	public void addDayOff(Integer i) {
		$daysOff.add(i);
	}



	public void addSubject(Subject i) {
		$subjects.add(i);
	}



	public boolean canTeach(Lesson lesson) {

		assert lesson != null;

		if ($lessons.contains(lesson)) {

			return false;
		} else if (!canTeach(lesson.getSubject())) {

			return false;
		} else if (lesson.getFlow().getPersonList().contains(this)) {

			return false;

		}
		return true;
	}



	public void merge(Teacher toMerge) {
		Subject subj = toMerge.getSubjects().get(0);
		$subjects.add(subj);
		$hours.put(subj, toMerge.getHours(subj));
		$groups.put(subj, toMerge.getGroups(subj));
	}



	public boolean canTeach(Subject subj) {
		if (!this.$hours.containsKey(subj)) {
			// System.out.println($hours.keySet()+" "+ subj.subjCode);

			return false;
		}
		if (this.$hours.get(subj) == 0) {
			// System.out.println($hours.get(subj)+" "+ subj.subjCode);

			return false;
		}

		return true;

	}



	public List<Subject> getSubjects() {
		assert Start.data.getSubjects().containsAll($subjects);
		return $subjects;
	}



	@Override
	public String toString() {
		String retStr = $name + " [";

		Iterator<Entry<Subject, Integer>> it = $hours.entrySet().iterator();
		while (it.hasNext()) {
			Entry<Subject, Integer> entry = it.next();
			retStr += "[ " + entry.getKey().getSubjCode() + " : "
					+ entry.getValue() + " ] ";
		}
		retStr += " ]";

		return retStr;
	}



	public Set<Integer> getDaysOff() {
		return $daysOff;
	}



	public Set<Group> getGroups(Subject subj) {
		return $groups.get(subj);
	}



	public void setGroups(Subject subj, Set<Group> groups) {
		this.$groups.put(subj, groups);
	}

}
